package com.demo.classloader;

import java.io.*;

/**
 * @author libo
 * @version 1.0
 * @date 2018/6/4 16:12
 */
public class TestClassLoader extends ClassLoader {

    private String classLoaderName;

    private final String fileExtension = ".class";

    private String path;


    public TestClassLoader(String classLoaerName) {
        super();
        this.classLoaderName = classLoaderName;
    }

    public TestClassLoader(ClassLoader parent, String classLoaderName) {
        super(parent);
        this.classLoaderName = classLoaderName;
    }

    public void setPath(String path) {
        this.path = path;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        System.out.println("test class loader");
        byte[] data = loadClassData(name);
        return defineClass(name, data, 0, data.length);
    }

    private byte[] loadClassData(String className) {
        InputStream inputStream = null;
        byte[] data = null;
        ByteArrayOutputStream baos = null;
        try {
            className = className.replace(".","\\");
            inputStream = new FileInputStream(new File(this.path + className + this.fileExtension));
            baos = new ByteArrayOutputStream();
            int length;
            while (-1 != (length = inputStream.read())) {
                baos.write(length);
            }
            data = baos.toByteArray();

            return data;
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return data;
    }


    @Override
    public String toString() {
        return "[" + this.classLoaderName + "]";
    }

    public static void main(String[] args)
            throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        TestClassLoader loader1 = new TestClassLoader("loader1");
        loader1.setPath("C:\\Users\\YITONG\\Desktop\\");
        Class<?> clazz = loader1.loadClass("com.demo.Example");
        System.out.println(clazz.hashCode());
        Object object = clazz.newInstance();
        System.out.println(object);
        System.out.println("=======");
        loader1 = null;
        clazz = null;
        object = null;

        System.gc();

        System.out.println();

        loader1 = new TestClassLoader("loader1");
        loader1.setPath("C:\\Users\\YITONG\\Desktop\\");
        clazz = loader1.loadClass("com.demo.Example");
        System.out.println(clazz.hashCode());
        object = clazz.newInstance();
        System.out.println(object);
        System.out.println("=======");
    }
}
